﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Windows.ApplicationModel.Activation;
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=391641

namespace VoiceSnap
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Windows.Media.Capture.MediaCapture captureManager;
        private readonly string PhotoFileName = "TestPhoto.jpg";
        private string nextPhotoTag = "";

        public MainPage()
        {
            this.InitializeComponent();

            this.NavigationCacheMode = NavigationCacheMode.Required;
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.
        /// This parameter is typically used to configure the page.</param>
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Initialize and start preview mode for camera
            imageCaptured.Source = null;

            // Find and use a rear-facing camera--not an FFC!
            var cameraSettings = new MediaCaptureInitializationSettings();
            cameraSettings.PhotoCaptureSource = PhotoCaptureSource.Photo;

            DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
            foreach (DeviceInformation info in devices)
            {
                if (info.EnclosureLocation != null && info.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back)
                {
                    cameraSettings.VideoDeviceId = info.Id;
                    break;
                }
            }

            string errorMessage = "";

            if (captureManager == null)
            {
                try
                {
                    captureManager = new Windows.Media.Capture.MediaCapture();
                    await captureManager.InitializeAsync(cameraSettings);
                }
                catch (Exception cameraCreationError)
                {
                    errorMessage = String.Format(
                        "An error occurred initializing a new camera object.\r\n\r\n{0:x}\r\n\r\n{1}",
                        cameraCreationError.HResult,
                        cameraCreationError.Message);
                }
            }
            else
            {
                try
                {
                    await captureManager.StopPreviewAsync();
                }
                catch (Exception cameraError)
                {
                    errorMessage = String.Format(
                        "An error occurred stopping a previous camera object preview.\r\n\r\n{0:x}\r\n\r\n{1}",
                        cameraError.HResult,
                        cameraError.Message);
                }
            }

            if (errorMessage != "")
            {
                await new MessageDialog(errorMessage).ShowAsync();
            }

            captureManager.SetRecordRotation(VideoRotation.Clockwise90Degrees);
            captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);

            try
            {
                capturePreview.Source = captureManager;
                await this.captureManager.StartPreviewAsync();
            }
            catch (Exception cameraException)
            {
                errorMessage = String.Format(
                    "An error occurred starting the camera preview.\r\n\r\n{0:x}\r\n\r\n{1}",
                    cameraException.HResult,
                    cameraException.Message);
            }

            if (errorMessage != "")
            {
                await new MessageDialog(errorMessage).ShowAsync();
            }

            // Consume Voice command arguments which were passed down to this page on activation.
            VoiceCommandActivatedEventArgs vcArgs = e.Parameter as VoiceCommandActivatedEventArgs;
            if (vcArgs != null)
            {
                IReadOnlyList<string> recognizedVoiceCommandPhrases;
                if (vcArgs.Result.SemanticInterpretation.Properties.TryGetValue("PhotoTag", out recognizedVoiceCommandPhrases))
                {
                    nextPhotoTag = recognizedVoiceCommandPhrases.First();
                    if (nextPhotoTag == "...")
                    {
                        this.vcTagBlock.Text = "PhraseTopic didn't resolve (...) - try again!";
                    }
                    else
                    {
                        this.vcTagBlock.Text = "Tagging with: " + nextPhotoTag;
                    }
                }
            }
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            capturePreview.Source = null;

            if (captureManager != null)
            {
                captureManager.Dispose();
            }

            captureManager = null;

            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Captures a photo and saves it to Picture library on the phone
        /// and displays a thumbnail of captured photo on the screen.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void TakePicture(object sender, RoutedEventArgs e)
        {
            ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();

            // create storage file in local app storage
            StorageFile file =
                await Constants.ImageSearchLocation.CreateFileAsync(
                    PhotoFileName,
                    CreationCollisionOption.GenerateUniqueName);

            // Take a photo and save it
            await captureManager.CapturePhotoToStorageFileAsync(imgFormat, file);

            // Add tags from Voice Commands, if they were provided
            if (nextPhotoTag != "" && nextPhotoTag != "...")
            {
                var imageProperties = await file.Properties.GetImagePropertiesAsync();
                imageProperties.Keywords.Add(nextPhotoTag);
                await imageProperties.SavePropertiesAsync();
            }

            // Get photo as a BitmapImage
            var photoStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
            BitmapImage bmpImage = new BitmapImage();
            bmpImage.SetSource(photoStream);

            // Display thumbnail of the photo that was captured.
            imageCaptured.Source = bmpImage;
        }

        /// <summary>
        /// Navigate to the application page with photo library search functionality.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NavigateToPhotoSearch(object sender, RoutedEventArgs e)
        {
            var rootFrame = Window.Current.Content as Frame;
            Debug.Assert(rootFrame.Navigate(typeof(ShowMe)), "Failed to create initial page");
        }
    }
}
